home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / web / noweb / src / c / modules.c < prev    next >
C/C++ Source or Header  |  1995-02-24  |  6KB  |  219 lines

  1. #line 52 "modules.nw"
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <ctype.h>
  6. #include "modules.h"
  7. #include "modtrees.h"
  8. #include "errors.h"
  9. #include "columns.h"
  10. #include "strsave.h"
  11.  
  12. #line 114 "modules.nw"
  13. static struct modpart *
  14. newmodpart(int type, char *s, Location *loc);   /* create a new module part */
  15.  
  16. static
  17. void append(Module mp, struct modpart *p);
  18. #line 223 "modules.nw"
  19. static int seekcycle(Module mp, Parent parent);
  20. #line 137 "modules.nw"
  21. static char *lastfilename = 0;
  22. static int lastlineno = -1;
  23. #line 42 "modules.nw"
  24. Module newmodule (char *modname) {
  25.     Module p = (Module) malloc (sizeof (struct module));
  26.     checkptr(p);
  27.     p->name = strsave(modname);
  28.     p->usecount = 0;
  29.     p->head = p->tail = NULL;
  30.     return p;
  31. }
  32. #line 75 "modules.nw"
  33. void add_part (Module mp, char *s, Parttype type, Location *loc) {
  34.     struct modpart *p = newmodpart(type,s,loc);
  35.     append (mp,p);
  36. }
  37. #line 81 "modules.nw"
  38. static struct modpart *
  39. newmodpart(int type, char *s, Location *loc) {
  40.     struct modpart *p = (struct modpart *) malloc (sizeof (struct modpart));
  41.     checkptr(p);
  42.     p->ptype = type;
  43.     if (s) {
  44.         p->contents = strsave(s);
  45.         
  46. #line 108 "modules.nw"
  47. { int k = strlen(p->contents)-1;
  48.   if (p->contents[k] == '\n') p->contents[k] = '\0';
  49.   else impossible("input line doesn't end with newline");
  50. }
  51. #line 89 "modules.nw"
  52.     }
  53.     if (loc) p->loc = *loc;
  54.     p->next = NULL;
  55.     return p;
  56. }
  57. #line 96 "modules.nw"
  58. static
  59. void append(Module mp, struct modpart *p) {
  60.     /* append p to mp's list of modparts */
  61.     if (mp->head == NULL) {
  62.         mp->head = mp->tail = p;
  63.     } else {
  64.         mp->tail->next = p;
  65.         mp->tail = p;
  66.     }
  67. }
  68. #line 143 "modules.nw"
  69. void resetloc(void) {
  70.   lastfilename = 0;
  71.   lastlineno = -1;
  72. }
  73. #line 151 "modules.nw"
  74. int expand (Module mp, int indent, int partial_distance, Parent parent,  
  75.             char *locformat, FILE *out) {
  76.     struct modpart *p;
  77.     Module newmod;
  78.     int error=Normal;
  79.     struct parent thismodule; /* the value only matters when we're expanding a module */
  80.  
  81.     
  82. #line 173 "modules.nw"
  83. thismodule.this = mp;
  84. thismodule.parent = parent;
  85. #line 159 "modules.nw"
  86.     
  87. #line 218 "modules.nw"
  88. if (seekcycle(mp, parent)) {
  89.     errormsg(Error, "<<%s>>", mp->name);
  90.     return Error;
  91. }
  92.  
  93. #line 161 "modules.nw"
  94.     for (p=mp->head; p!=NULL; p=p->next) {
  95.         switch (p->ptype) {
  96.             case STRING:  
  97. #line 186 "modules.nw"
  98. if (*(p->contents) != '\0') {
  99.     if (*locformat) {
  100.         if (printloc(out,locformat,p->loc,partial_distance) && (p != mp->head))
  101.               indent_for(partial_distance, out);
  102.     } else if (partial_distance == 0) {
  103.         indent_for(indent, out);
  104.         partial_distance = indent;
  105.     }
  106.     fprintf(out,"%s",p->contents);
  107.     partial_distance = limitcolumn(p->contents, partial_distance);
  108. }
  109. #line 163 "modules.nw"
  110.                                             ;  break;
  111.             case MODULE:  
  112. #line 204 "modules.nw"
  113. newmod = lookup(p->contents);
  114. if (newmod==NULL) {
  115.     errormsg (Error, "undefined module name: <<%s>>", p->contents);
  116.     error=Error;
  117. } else {
  118.     int retcode;
  119.     retcode = expand (newmod, partial_distance, partial_distance,
  120.                       &thismodule, locformat, out);
  121.     if (retcode > error) error = retcode;
  122. }
  123. partial_distance = limitcolumn(p->contents, partial_distance + 2) + 2; 
  124.                                 /* account for surrounding brackets */
  125. #line 164 "modules.nw"
  126.                                              ; break;
  127.             case NEWLINE: 
  128. #line 198 "modules.nw"
  129. partial_distance = 0;
  130. putc('\n', out);
  131. lastlineno++;
  132. #line 165 "modules.nw"
  133.                                              ; break;
  134.             default: impossible("bad part type");
  135.         }
  136.     }
  137.     return error;
  138. }
  139. #line 225 "modules.nw"
  140. static int seekcycle(Module mp, Parent parent) {
  141.     if (parent == NULL) {
  142.         return 0;
  143.     } else if (parent->this == mp || seekcycle(mp, parent->parent)) {
  144.         if (parent->this == mp)
  145.             fprintf(stderr, "Cyclic code chunks: ");
  146.         fprintf(stderr, "<<%s>> -> ", parent->this->name);
  147.         return 1;
  148.     } else {
  149.         return 0;
  150.     }
  151. }
  152. #line 247 "modules.nw"
  153. int printloc(FILE *fp, char *fmt, Location loc, int partial) {
  154.     char *p;
  155.     if (*fmt
  156.     && (loc.filename!=lastfilename || lastlineno != loc.lineno)) {
  157.         if (partial) putc('\n',fp);
  158.         
  159. #line 260 "modules.nw"
  160. for (p = fmt; *p; p++) {
  161.     if (*p == '%') {
  162.         switch (*++p) {
  163.             case '%': putc('%', fp);                             break;
  164.             case 'N': putc('\n', fp);                            break;
  165.             case 'F': fprintf(fp, "%s", loc.filename);           break;
  166.             case 'L': fprintf(fp, "%d", loc.lineno);             break;
  167.             case '-': case '+': 
  168.                         if (isdigit(p[1]) && p[2] == 'L') {
  169.                           fprintf(fp, "%d", *p == '+' ? loc.lineno + (p[1] - '0')
  170.                                                       : loc.lineno - (p[1] - '0'));
  171.                           p += 2;
  172.                         } else
  173.                           
  174. #line 280 "modules.nw"
  175. { static int complained = 0;
  176.   if (!complained) {
  177.     errormsg(Error,"Bad format sequence ``%%%c'' in -L%s",*p,fmt);
  178.     complained = 1;
  179.   }
  180. }
  181. #line 274 "modules.nw"
  182.                       break;            
  183.             default:  
  184. #line 280 "modules.nw"
  185. { static int complained = 0;
  186.   if (!complained) {
  187.     errormsg(Error,"Bad format sequence ``%%%c'' in -L%s",*p,fmt);
  188.     complained = 1;
  189.   }
  190. }
  191. #line 275 "modules.nw"
  192.                                                                 break;
  193.         }
  194.     } else putc(*p, fp);
  195. }
  196. #line 253 "modules.nw"
  197.         lastfilename = loc.filename;
  198.         lastlineno = loc.lineno;
  199.         return 1;
  200.     } else return 0;
  201. }
  202. #line 306 "modules.nw"
  203. void remove_final_newline (Module mp) {
  204.         /* remove trailing newline that must be in module */
  205.     if (mp->tail==NULL) /* module has no text */
  206.         return;
  207.     if (mp->tail->ptype != NEWLINE)
  208.         /* do nothing --- this is possible with nuweb front end
  209.               formerly: impossible("Module doesn't end with newline"); */
  210.         ;
  211.     else if (mp->tail == mp->head)
  212.             mp->head = mp->tail = NULL;
  213.     else {
  214.         struct modpart *p = mp->head;
  215.         while (p->next != mp->tail) p = p->next;
  216.         p->next = NULL;
  217.     }
  218. }
  219.